﻿using FinMkts.Messaging.Pgm;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace FinMkts.Messaging.UnitTests
{
    ///<summary>
    ///  This is a test class for BinarySizeTest and is intended
    ///  to contain all BinarySizeTest Unit Tests
    ///</summary>
    [TestClass]
    public class BinarySizeTest
    {
        ///<summary>
        ///  Gets or sets the test context which provides
        ///  information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext { get; set; }

        [TestMethod]
        public void BinarySizeDefaultConstructorTest()
        {
            var target = new BinarySize();
            Assert.AreEqual(0ul, target.Bytes);
        }

        [TestMethod]
        public void BinarySizeConstructorTest()
        {
            ulong bytes = 1;
            var target = new BinarySize(bytes);
            Assert.AreEqual(bytes, target.Bytes);
        }

        [TestMethod]
        public void StronglyTypedEquals_returnsTrue_forEqualObjects()
        {
            var target = BinarySize.Zero;
            var other = new BinarySize();
            Assert.IsTrue(target.Equals(other));
            Assert.IsTrue(other.Equals(target));
        }

        [TestMethod]
        public void StronglyTypedEquals_returnsFalse_forEqualObjects()
        {
            var target = BinarySize.Zero;
            var other = new BinarySize(1);
            Assert.IsFalse(target.Equals(other));
            Assert.IsFalse(other.Equals(target));
        }

        [TestMethod]
        public void EqualsTest_returnsTrue_forEqualObject()
        {
            var target = new BinarySize();
            object obj = BinarySize.Zero;
            Assert.IsTrue(target.Equals(obj));
        }

        [TestMethod]
        public void EqualsTest_returnsFalse_forNullObject()
        {
            var target = new BinarySize();
            object obj = null;
            Assert.IsFalse(target.Equals(obj));
        }

        [TestMethod]
        public void FromBytesTest()
        {
            ulong bytes = 10;
            var expected = new BinarySize(10);
            BinarySize actual = BinarySize.FromBytes(bytes);
            Assert.AreEqual(expected, actual);
            Assert.AreEqual(bytes, actual.Bytes);
        }

        [TestMethod]
        public void FromGigaBitsTest()
        {
            double gigaBits = 1d;
            var expected = new BinarySize(1024 * 1024 * 1024 / 8); 
            BinarySize actual = BinarySize.FromGigaBits(gigaBits);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void FromGigaBytesTest()
        {
            double value = 1d;
            var expected = new BinarySize(1024 * 1024 * 1024);
            BinarySize actual = BinarySize.FromGigaBytes(value);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void FromKiloBitsTest()
        {
            ulong value = 56; 
            var expected = new BinarySize(value * 1024 / 8);
            BinarySize actual = BinarySize.FromKiloBits(value);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void FromKiloBytesTest()
        {
            double value = 1d; 
            var expected = new BinarySize(1024); 
            BinarySize actual = BinarySize.FromKiloBytes(value);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void FromMegaBitsTest()
        {
            double value = 1d; 
            var expected = new BinarySize(1024 * 1024 / 8);
            BinarySize actual = BinarySize.FromMegaBits(value);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void FromMegaBytesTest()
        {
            double value = 1d; 
            var expected = new BinarySize(1024 * 1024);
            BinarySize actual = BinarySize.FromMegaBytes(value);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void GetHashCodeTest()
        {
            var target = new BinarySize(); 
            int expected = 0;
            int actual = target.GetHashCode();
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        [DeploymentItem("FinMkts.Messaging.dll")]
        public void ToBitsStringTest()
        {
            var target = new BinarySize_Accessor();
            string expected = "0.0 Kb";
            string actual = target.ToBitsString();
            Assert.AreEqual(expected, actual);
        }

        ///<summary>
        ///  A test for ToBytesString
        ///</summary>
        [TestMethod]
        [DeploymentItem("FinMkts.Messaging.dll")]
        public void ToBytesStringTest()
        {
            var target = new BinarySize_Accessor();
            string expected = "0 Bytes";
            string actual = target.ToBytesString();
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void ToStringTest()
        {
            var target = new BinarySize();
            string expected = "0 Bytes";
            string actual = target.ToString();
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void ToStringTestBitsOverload()
        {
            var target = new BinarySize(128);
            string expected = "1.0 Kb";
            string actual = target.ToString(BitsBytes.Bits);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void ToStringTestBytesOverload()
        {
            var target = new BinarySize(1024);
            string expected = "1.0 KB";
            string actual = target.ToString(BitsBytes.Bytes);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void op_AdditionTest()
        {
            var left = new BinarySize(1); 
            var right = new BinarySize(2); 
            var expected = new BinarySize(3);
            BinarySize actual = (left + right);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void op_EqualityTest()
        {
            var left = new BinarySize(1);
            var right = new BinarySize(1);
            Assert.IsTrue(left == right);
        }

        [TestMethod]
        public void op_InequalityTest()
        {
            var left = new BinarySize(1); 
            var right = new BinarySize(2);
            Assert.IsTrue(left != right);
        }

        [TestMethod]
        public void op_SubtractionTest()
        {
            var left = new BinarySize(4); 
            var right = new BinarySize(2);
            var expected = new BinarySize(2);
            BinarySize actual = (left - right);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void BytesTest()
        {
            ulong expected = 20;
            var target = new BinarySize(expected);
            ulong actual = target.Bytes;
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void GigaBitsTest()
        {
            double expected = 10;
            var target = new BinarySize((ulong) (expected * 1024 * 1024 * 1024 / 8));
            double actual = target.GigaBits;
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void GigaBytesTest()
        {
            double expected = 10;
            var target = new BinarySize((ulong)(expected * 1024 * 1024 * 1024));
            double actual = target.GigaBytes;
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void KiloBitsTest()
        {
            ulong expected = 10;
            var target = new BinarySize(expected * 1024 / 8);
            ulong actual = target.KiloBits;
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void KiloBytesTest()
        {
            double expected = 10;
            var target = new BinarySize((ulong)(expected * 1024));
            double actual = target.KiloBytes;
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void MegaBitsTest()
        {
            double expected = 10;
            var target = new BinarySize((ulong)(expected * 1024 * 1024 / 8));
            double actual = target.MegaBits;
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void MegaBytesTest()
        {
            double expected = 10;
            var target = new BinarySize((ulong)(expected * 1024 * 1024));
            double actual = target.MegaBytes;
            Assert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void BitConversions()
        {
            Assert.AreEqual(BinarySize.FromGigaBits(1), BinarySize.FromMegaBits(1024));
            Assert.AreEqual(BinarySize.FromMegaBits(1), BinarySize.FromKiloBits(1024));
        }

        [TestMethod]
        public void ByteConversions()
        {
            Assert.AreEqual(BinarySize.FromGigaBytes(1), BinarySize.FromMegaBytes(1024));
            Assert.AreEqual(BinarySize.FromMegaBytes(1), BinarySize.FromKiloBytes(1024));
            Assert.AreEqual(BinarySize.FromKiloBytes(1), BinarySize.FromBytes(1024));
        }

        [TestMethod]
        public void BitByteConversions()
        {
            Assert.AreEqual(BinarySize.FromGigaBytes(1), BinarySize.FromGigaBits(8));
            Assert.AreEqual(BinarySize.FromMegaBytes(1), BinarySize.FromMegaBits(8));
            Assert.AreEqual(BinarySize.FromKiloBytes(1), BinarySize.FromKiloBits(8));
        }
    }
}
